package cate.game.activity.godtree;

import cate.common.table.activity.godtree.row.LevelRewardRow;
import cate.common.table.activity.godtree.row.MonsterConfigRow;
import cate.common.table.d.*;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleFuncActivitySingle;
import cate.game.activity.godtree.msg.GodTreeInfoResp;
import cate.game.activity.warorder.RoleWarOrder;
import cate.game.fight.task.FightTask;
import cate.game.play.part.FightSide;
import cate.game.play.proce.play.PlayPO;
import cate.game.res.MixRes;
import cate.game.role.Role;
import cate.game.role.farm.IFarm;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GodTreeActivity extends RoleFuncActivitySingle implements IFarm {
    @NoteField("神树等级")
    public int level;
    @NoteField("今天打败了几只果实")
    public int kill;
    @NoteField("已扫荡次数")
    public int mopTimes;
    @NoteField(value = "战斗")
    public boolean fighting;
    @NoteField(value = "通关奖励领取记录")
    public Map<Integer, Boolean> takeMap;
    @NoteField(value = "今天打过的位置")
    public List<Integer> killPos;
    @NoteField(value = "今天是否升级过")
    private boolean levelUp;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (takeMap == null) {
            takeMap = new HashMap<>();
        }
        if (killPos == null) {
            killPos = new ArrayList<>();
        }
        FightTask task = role.getGame().fight.task.getTask(role, getFightFuncId());
        fighting = task != null && !task.invalid();
    }

    @Override
    public void onEnter() {
        super.onEnter();
        FightTask task = role.getGame().fight.task.getTask(role, getFightFuncId());
        fighting = task != null && !task.invalid();
        if (level == 0 && this.isOpen()) {
            level = 100;
        }
    }

    public GameResult<GodTreeActivity> challenge(int pos) {
        GameResult<GodTreeActivity> r = new GameResult<>();
        r.data = this;
        if (isFighting()) {
            return r.fail("当前战斗未结束");
        }
        if (pos <= 0 || pos > findConfigList(this.level).size()) {
            return r.fail("位置错误！");
        }
        MonsterConfigRow configRow = findConfigRow(level, kill + 1);
        if (configRow == null) {
            return r.fail("果子不存在！");
        }
        if (killPos.contains(pos)) {
            return r.fail("已经打过的果子！");
        }
        return doChallenge(configRow, GDPosition.DEFAULT_POS_NUM, pos);
    }

    public GameResult<GodTreeActivity> doChallenge(MonsterConfigRow tpl, byte posNum, int pos) {
        GameResult<GodTreeActivity> r = new GameResult<>();
        r.data = this;
        GodTreeFTC context = new GodTreeFTC(role, funcId(), tpl, pos);
        context.playStory.level = tpl.id;
        context.playStory.playIndex = posNum;
        context.setPositionApply(GDFunc.ADVENTURE);
        EcResult<FightSide> fsr = role.getGame().fight.side.createFightSideByCode(GDFight.Team.B, tpl.monster);
        if (!fsr.ok()) {
            return r.fail(fsr);
        }
        EcResult<PlayPO> play_r = role.getGame().play.startByRole(role, context, fsr.data);
        if (!play_r.ok()) {
            return r.fail(play_r);
        }
        startFighting();
        return r.success();
    }

    public void killAdd(int pos) {
        this.killPos.add(pos);
        this.kill++;
    }


    public void tryLevelUp(MonsterConfigRow configRow) {
        if (configRow == null) {
            return;
        }
        List<MonsterConfigRow> configList = findConfigList(this.level);
        if (configList == null || configList.isEmpty()) {
            return;
        }
        if (!levelUp && this.killPos.size() >= configList.size()) {
            LevelRewardRow row = findRewardRowByLevel(this.level);
            if (row != null && !takeMap.containsKey(row.id)) {
                takeMap.put(row.id, false);
            }
            if (configRow.nextLevel > 0 && role.getBase().level >= configRow.nextLevel) {
                this.level = configRow.nextLevel;
                this.levelUp = true;
            }
        }
        noticeUpdate();
    }

    public GameResult<GodTreeActivity> takePassReward(int tid) {
        GameResult<GodTreeActivity> r = new GameResult<>();
        r.data = this;
        LevelRewardRow row = findRewardRow(tid);
        if (row == null) {
            return r.fail("奖励不存在");
        }
        if (!takeMap.containsKey(tid)) {
            return r.fail("奖励不可领");
        }
        if (takeMap.get(tid)) {
            return r.fail("奖励已领取");
        }
        MixRes res = new MixRes(row.passReward);
        res.addAndDialog(role, true, GDOperation.GOD_TREE_PASS, tid);
        takeMap.put(tid, true);
        return r;
    }

    public GameResult<GodTreeActivity> mop() {
        GameResult<GodTreeActivity> r = new GameResult<>();
        r.data = this;
        RoleWarOrder single = role.getActivity().getActivitySingle(GDFunc.GOD_TREE_ORDER);
        if (!single.level.activeAdvance()) {
            return r.fail("解锁神树犒赏才能扫荡");
        }
        if (mopTimes >= GDGodTree.MOP_TIMES) {
            return r.fail("今日扫荡次数已用尽");
        }
        LevelRewardRow row = findRewardRowByLevel(this.level);
        if (row == null) {
            return r.fail("奖励不存在");
        }
        MixRes res = new MixRes(row.mopReward);
        res.addAndDialog(role, true, GDOperation.GOD_TREE_MOP, row.id);
        mopTimes++;
        return r;
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        this.killPos.clear();
        this.kill = 0;
        this.mopTimes = 0;
        this.levelUp = false;
        if (!silence) {
            noticeUpdate();
        }
    }

    @Override
    protected void onAfterOpen() {
        level = 100;
        noticeUpdate();
    }

    @Override
    public void onRoleOpen() {

    }

    @Override
    public void onRoleEnd() {

    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {

    }

    public void noticeUpdate() {
        role.sendNow(new GodTreeInfoResp(this));
    }

    @Override
    protected boolean activitySpecialCheckOpen() {
        return role.getBag().hero.getList().stream().anyMatch(hero -> {
            if (hero != null && hero.getTpl(role.toPlayBuildContext()) != null) {
                return hero.getTpl(role.toPlayBuildContext()).star >= GDGodTree.OPEN_STAR;
            }
            return false;
        });
    }

    public LevelRewardRow findRewardRowByLevel(int level) {
        return role.getGame().table.godTree.levelReward.getRowByLevel(level);
    }

    public LevelRewardRow findRewardRow(int tid) {
        return role.getGame().table.godTree.levelReward.get(tid);
    }

    public MonsterConfigRow findConfigRow(int level, int kill) {
        return role.getGame().table.godTree.monsterConfig.getRowByLevelAndNum(level, kill);
    }

    public List<MonsterConfigRow> findConfigList(int level) {
        return role.getGame().table.godTree.monsterConfig.getRowsByLevel(level);
    }

    @Override
    public int getFightFuncId() {
        return funcId();
    }

    @Override
    public boolean isFighting() {
        return fighting;
    }

    @Override
    public void startFighting() {
        this.fighting = true;
    }

    @Override
    public void endFighting() {
        this.fighting = false;
    }

    public boolean GMLevelUp(int level) {
        LevelRewardRow row = findRewardRowByLevel(level);
        if (row == null) {
            return false;
        }
        this.level = level;
        return true;
    }
}
